﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ObviousCode.Stately
{
    public class CompleteRequest : ITransitionRequest
    {
        static CompleteRequest _request = new CompleteRequest();

        public RequestType TransitionType { get { return RequestType.CompleteRequest; } }
        public static CompleteRequest Instance { get { return _request; } }
    }


    public class HaltRequest : ITransitionRequest
    {
        static HaltRequest _request = new HaltRequest();

        public RequestType TransitionType { get { return RequestType.HaltRequest; } }
        public static HaltRequest Instance { get { return _request; } }
    }

    public class WaitRequest : ITransitionRequest
    {
        static WaitRequest _request = new WaitRequest();

        public RequestType TransitionType { get { return RequestType.WaitRequest; } }
        public static WaitRequest Instance { get { return _request; } }
    }

    public class TransitionRequest<TState, TData> : ITransitionRequest where TState : struct, IConvertible
    {
        public TState StateRequest { get; protected set; }
        public TData Data { get; protected set; }

        public static TransitionRequest<TState, TData> For(TState state, TData data)
        {
            TransitionRequest<TState, TData> request = new TransitionRequest<TState, TData>();

            request.StateRequest = state;
            request.Data = data;

            return request;
        }

        public RequestType TransitionType { get { return RequestType.TransitionRequest; } }
    }

    public class TransitionRequest<TState> : TransitionRequest<TState, object>, ITransitionRequest where TState : struct, IConvertible
    {
        public static TransitionRequest<TState> For(TState state)
        {
            return For(state, null);
        }

        public static new TransitionRequest<TState> For(TState state, object data)
        {
            TransitionRequest<TState> transition = new TransitionRequest<TState>();

            transition.StateRequest = state;
            transition.Data = data;

            return transition;
        }
    }
}
